#include"../include/file_descriptor.h"
#include"../include/block.h"
#include"../include/main_header.h"
#include<string.h>
#include<stdio.h>
void create_file(char *path,char *name,char *content)
{
	struct file_descriptor f,fptr;
	struct block b;
	
	
//make file descriptor
	strcpy(f.file_name,name);
	strcpy(f.file_type,"txt");
	f.file_size=strlen(content);
	f.start_block_address=get_free_block();
	f.dir_descriptors=0;
	
	

//traverrse the path if file is not going to be stored in root dir  e.g. /folder1/folder2/file.txt
	if(strlen(path)>1)
	{
		fptr=traverse_path(path);
		
		fptr.dir_descriptors++;
		fseek(fp,fptr.descriptor_address,0);
		printf("\n%ld\n",ftell(fp));		
		fwrite(&fptr,sizeof(struct file_descriptor),1,fp);
		
		fseek(fp,fptr.start_block_address,0);
		fseek(fp,(fptr.dir_descriptors-1)*sizeof(struct file_descriptor),1);
		f.descriptor_address=ftell(fp);			
		
	}
//if the file is going to be stored in root directory	
	else
	{
	fseek(fp,sizeof(struct main_header) + m.root_descriptors*sizeof(struct file_descriptor) ,0);	
	f.descriptor_address=ftell(fp);
	printf("\n%ld\n",ftell(fp));
	m.root_descriptors++;
	//m.fd_used++;
			
	}
//take content in b.data	
	strcpy(b.data,content);

//store address FFFF showing end of file 	
	b.next=0xFFFF;	
	
//write the file desccriptor 
	fwrite(&f,sizeof(struct file_descriptor),1,fp);
	
//write the content of the file	
	fseek(fp,f.start_block_address,0);
	fwrite(&b,sizeof(struct block),1,fp);

//update meta header	
	update_main_header();
}

//to create directory
void make_dir(char *path,char *name)
{
	struct file_descriptor f;
	struct file_descriptor fptr;
	struct block b;
	unsigned long int temp,current_block;
	int j,k;
//make the file descriptor
	strcpy(f.file_name,name);	
	strcpy(f.file_type,"dir");
	f.file_size=0;
	f.start_block_address=get_free_block();
	f.dir_descriptors=0;
	
	
			
	if(strlen(path)>1)
	{
		fptr=traverse_path(path);
				
		fptr.dir_descriptors++;
		
		fseek(fp,fptr.descriptor_address,0);
		//printf("\n%ld\n",ftell(fp));		
		fwrite(&fptr,sizeof(struct file_descriptor),1,fp);
		
		fseek(fp,fptr.start_block_address,0);
		//printf("\n%ld\n",ftell(fp));		
		j=1;	
		k=1;
		current_block=ftell(fp);
		fread(&b,sizeof(struct block),1,fp);	
		fseek(fp,-(sizeof(struct block)),1);	
		//printf("\n%ld     %d\n",ftell(fp),fptr.dir_descriptors);	
		//while(1);
		while(j<=(fptr.dir_descriptors-1))
		{
			fseek(fp,sizeof(struct file_descriptor),1);
			printf("\n%ld\n",ftell(fp));
			
			if(j==k*BLOCK_DESCRIPTORS && j<(fptr.dir_descriptors-1))
			{
			fseek(fp,b.next,0);
			current_block=ftell(fp);
			fread(&b,sizeof(struct block),1,fp);
			fseek(fp,-(sizeof(struct block)),1);			
			k++;
			}
			
			else if(j==k*BLOCK_DESCRIPTORS && j==(fptr.dir_descriptors-1))
			{
			temp = get_free_block();
			b.next= temp;
			fseek(fp,current_block,0);
			fwrite(&b,sizeof(struct block),1,fp);
			fseek(fp,temp,0);
			}
			j++;
			
		}		
	f.descriptor_address=ftell(fp);	
	}
	else
	{
		fseek(fp,sizeof(struct main_header),0);
		j=1;	
		k=1;
		current_block=ftell(fp);
		fread(&b,sizeof(struct block),1,fp);	
		fseek(fp,-(sizeof(struct block)),1);	
			
		
		while(j<=m.root_descriptors)
		{
			fseek(fp,sizeof(struct file_descriptor),1);
			//printf("\n%ld\n",ftell(fp));
			
			if(j==k*BLOCK_DESCRIPTORS && j<m.root_descriptors)
			{
			fseek(fp,b.next,0);
			current_block=ftell(fp);
			fread(&b,sizeof(struct block),1,fp);
			fseek(fp,-(sizeof(struct block)),1);			
			k++;
			}
			
			else if(j==k*BLOCK_DESCRIPTORS && j==m.root_descriptors)
			{
			temp = get_free_block();
			b.next= temp;
			fseek(fp,current_block,0);
			fwrite(&b,sizeof(struct block),1,fp);
			fseek(fp,temp,0);
			}
			j++;
			
		}
	f.descriptor_address=ftell(fp);		
	m.root_descriptors++;
	//m.fd_used++;
			
	}
		
	
	
	
	fwrite(&f,sizeof(struct file_descriptor),1,fp);
	
	b.next=0xFFFF;	
	fseek(fp,f.start_block_address,0);	
	fwrite(&b,sizeof(struct block),1,fp);	
	
	update_main_header();

}
struct file_descriptor traverse_path(char *path)
{
	long int temp;	
	int i=0,j=1,k=0;
	struct file_descriptor f;
	struct block b;
	//struct file_descriptor fptr;
	int current_dir_descriptors=m.root_descriptors;	
	char dir[10];
	rewind(fp);	
	fseek(fp,sizeof(struct main_header),0);
	path++;	
	while((*path)!='\0')
	{
		i=0;
		while((*path)!='/')
		{
			dir[i]=*path;
			path++;
			i++;			
		}		
		dir[i]='\0';
		path++;		
		j=1;	
		k=1;
		fread(&b,sizeof(struct block),1,fp);	
		fseek(fp,-(sizeof(struct block)),1);	
		while(j<=current_dir_descriptors)
		{
			fread(&f,sizeof(struct file_descriptor),1,fp);
			//printf("\n%ld\n",ftell(fp));
			if(!strcmp(dir,f.file_name))
			{
				fseek(fp,f.start_block_address,0);
				current_dir_descriptors=f.dir_descriptors;
				break;
			}
			if(j==k*BLOCK_DESCRIPTORS && j<current_dir_descriptors)
			{
			fseek(fp,b.next,0);
			fread(&b,sizeof(struct block),1,fp);
			fseek(fp,-(sizeof(struct block)),1);			
			k++;
			}
			
			j++;
			
		}

	}
	
	//printf("%ld",ftell(fp));
	return f;
}

void listdir(char *path)
{

struct file_descriptor f,fptr;
struct block b;
int current_dir_descriptors;
unsigned long int current_block;
int i,j,k;
if(strlen(path)>1)
	{
		fptr=traverse_path(path);
		current_dir_descriptors=fptr.dir_descriptors;
		printf("--------descriptor details-------------");			
		printf("\nname:%s",fptr.file_name);		
		printf("\naddress:%ld",fptr.start_block_address);
		printf("\ndir descriptors:%d",fptr.dir_descriptors);		
		//printf("\nroot descriptors:%d",m.root_descriptors);
		printf("\nsize:%ld",fptr.file_size);
		printf("\ntype:%s",fptr.file_type);
		//printf("\nnext free:%ld",m.free_address);
		
		fseek(fp,fptr.start_block_address,0);
				
	}
	else
	{
	printf("--------it is a root directory-------------");
	fseek(fp,sizeof(struct main_header) ,0);	
	//fread(&m,sizeof(struct main_header),1,fp);
	current_dir_descriptors=m.root_descriptors;
	printf("\nroot descriptors:%d",current_dir_descriptors);
	}

		j=1;	
		k=1;
		current_block=ftell(fp);
		fread(&b,sizeof(struct block),1,fp);	
		fseek(fp,-(sizeof(struct block)),1);	
			
		
		while(j<=current_dir_descriptors)
		{
			//printf("%ld",ftell(fp);
			fread(&f,sizeof(struct file_descriptor),1,fp);
			print_descriptor(f);
			
			if(j==k*BLOCK_DESCRIPTORS && j<current_dir_descriptors)
			{
			fseek(fp,b.next,0);
			current_block=ftell(fp);
			fread(&b,sizeof(struct block),1,fp);
			fseek(fp,-(sizeof(struct block)),1);			
			k++;
			}
			
			
			j++;
			
		}	


}
void print_descriptor(struct file_descriptor f)
{
printf("\n-----------------------------------------------------\n");			
		printf("\nname:%s",f.file_name);		
		printf("\naddress:%ld",f.start_block_address);
		printf("\ndir descriptors:%d",f.dir_descriptors);		
		printf("\nroot descriptors:%d",m.root_descriptors);
		printf("\nsize:%ld",f.file_size);
		printf("\ntype:%s",f.file_type);
		printf("\nnext free:%ld",m.free_address);
		printf("\ndescriptor address:%ld",f.descriptor_address);


}
void listfile(char *path, char *name)
{
struct file_descriptor f,fptr;
struct block b;
int current_dir_descriptors;
int i=0;
if(strlen(path)>1)
	{
		fptr=traverse_path(path);
		current_dir_descriptors=fptr.dir_descriptors;
		fseek(fp,fptr.start_block_address,0);
				
	}
	else
	{
	
	fseek(fp,sizeof(struct main_header) ,0);	
	current_dir_descriptors=m.root_descriptors;
	printf("\nroot descriptors:%d",current_dir_descriptors);
	}

	while(i<current_dir_descriptors)
		{
			fread(&f,sizeof(struct file_descriptor),1,fp);
			
			if(!strcmp(name,f.file_name))
			{
				
				break;
			}
			i++;
		}
printf("\n-------file descriptor--------\n");
			
		printf("\nname:%s",f.file_name);		
		printf("\naddress:%ld",f.start_block_address);
		printf("\ndir descriptors:%d",f.dir_descriptors);		
		printf("\nroot descriptors:%d",m.root_descriptors);
		printf("\nsize:%ld",f.file_size);
		printf("\ntype:%s",f.file_type);
		printf("\nnext free:%ld",m.free_address);
printf("---------------filedata-------------------");
fseek(fp,f.start_block_address,0);
fread(&b,sizeof(struct block),1,fp);
printf("\nfile data:%s\n",b.data);
}

void list_files()
{	
	//fp=fopen("test","rb+");
	int i;
	struct file_descriptor f;
	struct block b;	
	rewind(fp);	
	fseek(fp,sizeof(struct main_header),0);
	
	for(i=0;i<m.root_descriptors;i++)
	{
		fread(&f,sizeof(struct file_descriptor),1,fp);
		printf("-----------------------------------------------------");			
		printf("\nname:%s",f.file_name);		
		printf("\naddress:%ld",f.start_block_address);
		printf("\ndir descriptors:%d",f.dir_descriptors);		
		printf("\nroot descriptors:%d",m.root_descriptors);
		printf("\nsize:%ld",f.file_size);
		printf("\ntype:%s",f.file_type);
		printf("\nnext free:%ld",m.free_address);
		
	}
	//fclose(fp);
}
void test()
{
struct file_descriptor f;
struct block b;
int i;
//fp=fopen("test","rb+");
rewind(fp);
fread(&m,sizeof(struct main_header),1,fp);
//printf("\nroot descriptors:%d",m.root_descriptors);
//traverse_path("/folder1/");
fseek(fp,380,0);
fread(&f,sizeof(struct file_descriptor),1,fp);
printf("-----------------------------------------------------");		
		//printf("\nfile %d:",i);		
		printf("\nname:%s",f.file_name);
		printf("\naddress:%ld",f.start_block_address);
		printf("\nsize:%ld",f.file_size);
		printf("\ntype:%s",f.file_type);
		//printf("\nvfs_label:%ld",m.free_address);
		printf("\ndir descriptors:%d",f.dir_descriptors);
		printf("\ndescriptor address:%ld",f.descriptor_address);
printf("-----------------------------------------------------");
///////////////////////////////////////////////////////////////////////////////////////
/*fseek(fp,176+32,0);
fread(&f,sizeof(struct file_descriptor),1,fp);
printf("-----------------------------------------------------");		
		//printf("\nfile %d:",i);		
		printf("\nname:%s",f.file_name);		
		printf("\naddress:%ld",f.start_block_address);
		printf("\nsize:%ld",f.file_size);
		printf("\ntype:%s",f.file_type);
		//printf("\nvfs_label:%ld",m.free_address);
		printf("\ndir descriptors:%d",f.dir_descriptors);
		printf("\ndescriptor address:%ld",f.descriptor_address);
printf("-----------------------------------------------------");
*/
/*fseek(fp,40,0);
	for(i=1;i<15;i++)
	{

		fread(&b,sizeof(struct block),1,fp);
		printf("\naddress:%ld\n",b.next);		
	}
*/
//fclose(fp);
}
void file_content()
{
struct block b;
//fp=fopen("test","rb+");
/*
fseek(fp,40,0);
fread(&b,sizeof(struct block),1,fp);
printf("\nfile 1:%s\n",b.data);
*/
fseek(fp,552,0);
fread(&b,sizeof(struct block),1,fp);
printf("\nfile 1:%s\n",b.data);

fseek(fp,1064,0);
fread(&b,sizeof(struct block),1,fp);
printf("\nfile 1:%s\n",b.data);

fseek(fp,1576,0);
fread(&b,sizeof(struct block),1,fp);
printf("\nfile 1:%s\n",b.data);

fseek(fp,4648,0);
fread(&b,sizeof(struct block),1,fp);
printf("\nfile 1:%s\n",b.data);

//fclose(fp);

}
